package com.gcstorage.tvdev.net;

import android.os.Build;

import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.gcstorage.tvdev.bean.HttpErrorLogBean;
import com.gcstorage.tvdev.util.SpUtils;
import com.google.gson.JsonElement;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Set;

import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * @author mrz
 * @date 2021/08/20 09:16
 * @description 网络请求错误信息上传
 */
public class ErrorResInterceptor implements Interceptor {
    /**
     * 日志上传api
     */
    private static final String api = "/api/blade-log/gcslog/server/upMyLog";

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        //提交访问出错日志
        if (request.headers().get("uploadError") == null) {
            Response response = chain.proceed(request);
            checkResponseError(request, response);
            return response;
        }
        return chain.proceed(request);
    }

    /**
     * 如果接口未正常返回 成功数据  上传错误数据到服务器
     */
    private void checkResponseError(Request request, Response response) {
        try {
            if (response.body() == null) {
                return;
            }
            int resCode = response.code();
            //目前仅上传400、500错误
            if (String.valueOf(resCode).startsWith("4") || String.valueOf(resCode).startsWith("5")) {
                String result = response.body().string();
                HttpErrorLogBean bean = new HttpErrorLogBean();
                bean.setWebMonitorId("webfunny55368");
                bean.setUserId(SpUtils.getString(SpUtils.TAG_USER, "user_id", ""));
                bean.setUploadType("HTTP_LOG");
                bean.setHappenTime(TimeUtils.getNowMills());
                bean.setCustomerKey(bean.getUserId() + TimeUtils.getNowString(new SimpleDateFormat("yyyyMMdd", Locale.CHINA)));
                bean.setCompleteUrl(response.request().url().toString());
                bean.setHttpUrl(response.request().url().toString());
                bean.setStatus(String.valueOf(resCode));
                bean.setStatusText("ok");
                bean.setStatusResult("请求返回");
                bean.setRequestText(GsonUtils.toJson(buildRequestInfo(request)));
                bean.setResponseText(result);
                bean.setLoadTime(response.receivedResponseAtMillis() - response.sentRequestAtMillis());
                bean.setDeviceName(Build.BRAND + DeviceUtils.getModel());
                bean.setOs("android");
                uploadResError(bean);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 构建请求信息
     */
    private HashMap<String, Object> buildRequestInfo(Request request) {
        HashMap<String, String> reqHeader = parseHeaders(request.headers());
        String reqUrl = request.url().toString();

        LinkedHashMap<String, Object> map = new LinkedHashMap<>(4);
        RequestBody requestBody = request.body();

        if (requestBody != null) {
            if (requestBody instanceof MultipartBody) {
                MultipartBody multipartBody = (MultipartBody) requestBody;
                HashMap<String, Object> parameters = new HashMap<>(3);
                parameters.put("type", "MultipartBody");
                try {
                    parameters.put("contentLength", multipartBody.contentLength());
                } catch (IOException e) {
                    e.printStackTrace();
                    parameters.put("msg", "获取上传文件大小失败");
                }
                map.put("body", parameters);
            } else if (requestBody instanceof FormBody) {
                FormBody formBody = (FormBody) requestBody;
                HashMap<String, Object> parameters = new HashMap<>(formBody.size() + 1);
                parameters.put("type", "FormBody");
                for (int i = 0; i < formBody.size(); i++) {
                    String name = formBody.encodedName(i);
                    String value = formBody.encodedValue(i);
                    parameters.put(name, value);
                }
                map.put("body", parameters);
            }
            if (requestBody.contentType() != null) {
                map.put("contentType", requestBody.contentType().toString());
            }
        }
        map.put("url", reqUrl);
        map.put("headers", reqHeader);
        return map;
    }

    private void uploadResError(HttpErrorLogBean error) {
        try {
            //构建符合后台需求的请求参数
            // JSONArray objects = new JSONArray("[" + GsonUtils.toJson(error) + "]");
            HashMap<String, Object> parameters = new HashMap<>(1);
            parameters.put("logs", Collections.singletonList(error));

            HashMap<String, Object> request = new HashMap<>();
            request.put("logs", Collections.singletonList(error));

            //添加过滤请求头
            HashMap<String, Object> headers = new HashMap<>(1);
            headers.put("uploadError", "uploadError");

            HttpClient.get().postBody(SpUtils.getString("cityHost") + api, request, headers, new RxObserver() {
                @Override
                public void onSuccess(JsonElement t) {
                    LogUtils.d(t.toString());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * header组装
     */
    private HashMap<String, String> parseHeaders(Headers headers) {
        if (headers.size() == 0) {
            return null;
        }
        HashMap<String, String> resMap = new HashMap<>(headers.size());
        Set<String> names = headers.names();
        for (String key : names) {
            String value = headers.get(key);
            resMap.put(key, value);
        }
        return resMap;
    }


}
